home *** CD-ROM | disk | FTP | other *** search
- ;SPS.COM is a TSR program to do a selective print screen. It prints
- ;the characters within a box defined by the cursor position. When
- ;started, if P is pressed, the whole screen is printed, and if Esc
- ;is pressed, the print screen is aborted.
-
- Colormem equ 0B800h ;Color video mem for page 1
- Monomem equ 0B000h ;Mon video mem for page 1
- Timer equ 8 ;Timer int #
- Enterkey equ 28 ;Define scan codes
- Home equ 71
- Endkey equ 79
- Esc equ 1
- Lfarrow equ 75
- Rtarrow equ 77
- Uparrow equ 72
- Dnarrow equ 80
- Pgup equ 73
- Pgdn equ 81
- Cntrl equ 29 ;Scan code for control key
- Cntnot equ Cntrl+128 ;Scan code fpr control key release
- Lshrel equ 42+128 ;Scan code for left shift release
- Rshrel equ 54+128 ; " " " right " "
- Video equ 10h ;Bios video interrupt
- DOS equ 21h ;DOS interrupt
- Getvec equ 35h ;Get int vector DOS service
- Setvec equ 25h ;Set int vector DOS service
- Setcur equ 2 ;Set cursor pos video service
- Getcur equ 3 ;Get cursor pos video service
- Promptpos equ 25*160-36 ;5th char from end of screen
-
- jmp Initialize ;Install the program as int 5 (PrtScn)
-
- Oldint5:
- Oldoff5 dw ? ;Save old int 5 offset and segment here
- Oldseg5 dw ?
- Oldint8:
- Oldoff8 dw ?
- Oldseg8 dw ?
- Oldint9:
- Oldoff9 dw ? ;Save old keyboard int here
- Oldseg9 dw ?
- Vidmem dw ? ;Current video mem segment
- Curpos dw ? ;Cursor position at start
- Curtyp dw ? ;Cursor type
- Stloc dw 0 ;Start row:col of print box
- Endloc dw 184fh ;End row:col of print box
- Timeval db ?
- Vpage db ? ;Current video page
- Endflg db 0 ;1=> start row:col set
- Prtflg db 0 ;1=> screen has been printed
- Cntflg db 0 ;1=> Cntrl being pressed
- Row db ? ;Rows to print
- Col db ? ;Columns to print
- Buffer: dw 18 dup(?) ;Put original prompt data here
- Msg1: db 'Speptp psptpaprptp pppopspiptpipopnp'
- Msg2: db 'Speptp pepnpdp pppopspiptpipopnp p p'
- Msg3: db 'Pprpipnptpeprp pnpoptp prpepapdpyp p'
- Rowbuf: db 83 dup(?) ;Buffer for a screen row of chars
-
- Newint5: push bp,ax,bx,cx,dx,si,di,ds,es ;Save all for calling pgm
- mov bp,sp
- mov ds,cs ;Set both for this code
- mov es,cs
- mov cx,Colormem ;Assume color display
- mov ah,15 ;Get current video mode
- int Video
- mov Vpage,bh ;Save video page
- cmp al,2 ;Color?
- je A1 ;Yes
- cmp al,3 ;Color?
- je A1 ;Yes
- cmp al,7 ;Mono?
- je A0 ;Yes
- mov sp,bp
- pop es,ds,di,si,dx,cx,bx,ax,bp ;Restore all for calling pgm
- cs jmp far d[Oldint5] ;and do a graphics print screen
-
- ;Come here if 80 col text mode.
- A0: mov cx,Monomem ;Yes, set for Mono
- A1: mov bl,0 ;bx=page offset
- add cx,bx ;Video segment
- mov Vidmem,cx ;Save it
-
- ;Save old and install new Keyboard int 9 and Timer int 8 to this code.
- push ds
- mov ax,0 ;Set ds=0 (int area)
- mov ds,ax
- cli ;Disable interrupts
- mov ax,[32]
- mov bx,[34]
- mov cx,[36]
- mov dx,[38]
- mov cs:Oldoff8,ax
- mov cs:Oldseg8,bx
- mov cs:Oldoff9,cx ;to storage
- mov cs:Oldseg9,dx
- mov w[32],Newint8
- mov w[34],cs
- mov w[36],Newint9
- mov w[38],cs
- sti ;Enable ints
- pop ds
-
- ;Initialize variables.
- mov Stloc,0 ;Start of screen
- mov Endloc,184Fh ;End of screen
- mov Endflg,0 ;Clear flags
- mov Prtflg,0
- mov Cntflg,0
-
- ;Get current Cursor position and type.
- mov ah,Getcur ;Get cursor row:col
- mov bh,Vpage
- int Video
- mov Curpos,dx ;Save it
- mov Curtyp,cx ;Save cursor type
-
- ;Move cursor to top of screen.
- xor dx,dx ;Top of screen
- call Poscur
- mov cx,0607h ;Set new cursor
- mov ah,1
- int Video
-
- ;Get last 18 bytes from screen.
- push ds
- mov ax,Vidmem ;Set ds=Vidmem
- mov ds,ax
- mov si,Promptpos ;ds:si=prompt pos
- mov di,Buffer ;es:di=buffer
- mov cx,18 ;Get 18 words
- rep movsw ;to buffer
- pop ds
-
- ;Display prompt.
- mov si,Msg1 ;Print 'start' prompt
- call Prompt
-
- ;Hang up computer and wait for keyboard input.
- Waithere: jmp Waithere ;Wait for keyboard int
-
- Newint8:
- cs cmp Timeval,0
- je X1
- cs dec Timeval
- X1: cs jmp far d[Oldint8]
-
- ;This is the new Keyboard int 9 routine. Does not pass keys on to
- ;other programs, so they never know keys were pressed.
- Newint9: sti
- push ax ;Save reg
- in al,60h ;Get scan code
- cmp Prtflg,0 ;Is screen being printed?
- jne B0 ;Yes, clear keyboard and return from int
- cmp al,Lshrel ;Left shift release?
- je A2 ;Yes
- cmp al,Rshrel ;Right shift release?
- jne A3 ;No
- A2: pop ax
- cs jmp far d[Oldint9] ;Yes, send to BIOS
- ;No, process the key command.
- A3: cmp al,Home ;Home?
- jne C1 ;No
- xor dx,dx ;Set for start of screen
- B1: call Poscur ;Set cursor there
- ;Reset keyboard and sen End Of Interrupt
- B0: call Resetkbd ;Reset keyboard
- pop ax
- iret ;Send back to Wait line
-
- C1: cmp al,Endkey ;End key?
- jne C2 ;No
- mov dx,184Fh ;Set for end of screen
- jmp B1
-
- C2: cmp al,Uparrow ;Up arrow?
- jne C3 ;No
- cmp dh,0 ;On top line?
- je B0 ;Yes
- dec dh ;Dec row
- jmp B1
-
- C3: cmp al,Dnarrow ;Down arrow?
- jne C4 ;No
- cmp dh,24 ;On bottom row?
- je B0 ;Yes
- inc dh ;Inc row
- jmp B1
-
- C4: cmp al,Lfarrow ;Left arrow?
- jne C5 ;No
- cmp cs:Cntflg,0 ;Cntrl left arrow?
- je C4A ;No
- mov dl,0 ;Set for 1st col
- jmp B1
- C4A: cmp dl,0 ;At 1st col?
- je B0 ;Yes
- dec dl ;Dec col
- jmp B1
-
- C5: cmp al,Rtarrow ;Right arrow?
- jne C6 ;No
- cmp cs:Cntflg,0 ;Cntrl right arrow?
- je C5A ;No
- mov dl,79 ;Set for last col
- jmp B1
- C5A: cmp dl,79 ;At last col?
- je B0 ;Yes
- inc dl ;Inc col
- jmp B1
-
- C6: cmp al,Cntrl ;Control pressed?
- jne C7 ;No
- inc Cntflg ;Yes, set flag
- jmp B0
-
- C7: cmp al,Cntnot ;Cntrl key released?
- jne C8 ;No
- mov Cntflg,0 ;Clear flag
- jmp B0
-
- C8: cmp al,Esc ;Escape?
- jne C9 ;No
- jmp Exit ;Yes, exit
-
- C9: cmp al,25 ;Was a P?
- je Check ;Yes, print whole screen
-
- cmp al,Pgup ;Page up?
- jne D1 ;No
- mov dh,0 ;Set to top row
- jmp B1
-
- D1: cmp al,Pgdn ;Page down
- jne D3 ;No
- mov dh,24 ;Set to last row
- D2: jmp B1
-
- D3: cmp al,Enterkey ;Enter?
- jne D2 ;No, ignore the key and wait for another
- cmp Endflg,0 ;1st selection?
- jne D4 ;No
- mov Stloc,dx ;Save start box location
- inc Endflg ;=> start saved
- mov si,Msg2 ;Print End prompt
- call Prompt
- jmp B0 ;Get next command
- D4: mov Endloc,dx ;Save end location
-
- Check: mov si,Buffer ;ds:si=buffer
- call Prompt ;Put original data back on screen
- inc Prtflg ;Indicate printing has started
- mov ax,Stloc ;Get box start
- mov cx,Endloc ;Get box end
- sub ch,ah ;Rows OK?
- jc Exit ;No
- sub cl,al ;Cols OK?
- jc Exit ;No, exit
- add cx,0101h ;ah=rows, al=columns to do
- mov Row,ch ;Save them
- mov Col,cl
-
- ;Compute start offset.
- mov cl,al ;Save column
- mov ch,80 ;Chars/row
- xchg al,ah ;Get row to al
- mul ch ;ax=char offset to start of row
- mov ch,0 ;cx=column
- add ax,cx ;ax=char offset of start location
- shl ax,1 ;Byte offset since 2 bytes/char
- mov si,ax ;Save it
-
- ;Get a row of data to the buffer.
- E0: push ds
- mov ax,Vidmem ;Set ds=video mem
- mov ds,ax
- mov es,cs ;Set es this segment
- E1: mov cl,cs:Col ;Get cols to do
- mov ch,0 ;cx=cols to do
- mov di,Rowbuf ;es:di point to screen row buffer
- push si,di,cx ;Save pointers and count
- E2: lodsw ;Get char & attr from screen
- stosb ;Save char in row buffer
- loop E2 ;Do for all chars on row
- mov ax,0A0Dh ;Add a cr-lf
- stosw
- ;Ckeck for and replace (with a space) any control chars.
- pop cx,di ;Get cols and buffer pointer
- E3: mov al,cs:[di] ;Get a char from buffer
- cmp al,20h ;Control char?
- jb E4 ;Yes
- cmp al,0FFh ;Bad char?
- jb E5 ;No
- E4: mov cs:b[di],20h ;Replace with a space
- E5: inc di ;Point to next char
- loop E3 ;Check all
- ;Now send chars in buffer to printer.
- call Printer
- pop si ;Get start of row
- add si,160 ;Next row
- dec cs:Row ;Done all rows?
- jne E1 ;No
- pop ds
-
- ;Now exit.
- Exit: mov si,Buffer ;Put old screen data back
- call Prompt
- mov dx,cs:Curpos ;Restore Cursor
- call Poscur
- mov cx,cs:Curtyp
- mov ah,1
- int Video
- ;Set old keyboard and timer interrupts back.
- mov ax,0 ;Set ds=0 (int area)
- mov ds,ax
- cli ;Disable interrupts
- mov ax,cs:Oldoff8 ;Set old int 8
- mov bx,cs:Oldseg8
- mov cx,cs:Oldoff9 ;Set old int 9
- mov dx,cs:Oldseg9
- mov [32],ax
- mov [34],bx
- mov [36],cx
- mov [38],dx
- sti ;Enable ints
- call Resetkbd ;Reset the keyboard
- mov sp,bp
- pop es,ds,di,si,dx,cx,bx,ax,bp ;Restore all for calling pgm
- iret ;Return from interrupt
-
- ;Subroutines ---------------------------------------------------------
- Poscur: mov ah,Setcur ;Set cursor video service
- mov bh,Vpage ;Current video page
- int Video ;Set cursor pos
- ret
-
- Prompt: push ax,cx,es,di
- mov ax,Vidmem ;Set es=Video segment
- mov es,ax
- mov di,Promptpos ;es:di=prompt pos
- mov cx,18 ;18 words to move
- rep movsw ;Move them to video mem
- pop di,es,cx,ax
- ret
-
- Getkey: mov ah,0 ;Wait for key Keyboard service
- int 16h ;Do it
- ret
-
- Resetkbd: in al,61h ;Get current control value
- mov ah,al ;Save it in ah
- or al,80h ;Set msb
- out 61h,al ;Send it to control port
- mov al,ah ;Get original value
- out 61h,al ;Send it to control port
- cli ;Disable ints
- mov al,20h ;Send EOI value to 8259
- out 20h,al
- sti ;Enable ints
- ret
-
- ;Print the row of chars in the row buffer.
- Printer: push ds
- xor dx,dx ;Select LPT1
- mov ds,cs ;Set ds this code
- mov Timeval,36 ;Set a 2 second wait
- G1: call Getstat ;Get printer status
- cmp ah,90h ;OK?
- je G3 ;Yes
- cmp Timeval,0 ;Timed out?
- jne G1 ;No
- call PNR ;Print 'Printer not ready' prompt
- mov Timeval,180 ;Set a 10 second wait
- G2: call Getstat ;Get printer status
- cmp ah,90h ;OK now?
- je G8 ;Yes
- cmp Timeval,0 ;Timed out?
- jne G2 ;No
- jmp Exit ;Yes, give up
- G8: call PIB ;Put old screen back
- G3: mov si,Rowbuf ;ds:si points to row buffer
- mov cl,Col ;cx=Columns
- mov ch,0
- add cl,2 ;Add 2 for cr-lf at end
- G4: lodsb ;Get a char from buffer
- mov ah,0 ;Send char service
- int 17h ;no, send to printer
- test ah,10h ;Still selected?
- je G7 ;No
- loop G4 ;Yes, print next char
- pop ds
- ret
- G7: push si,cx ;Save position and count
- mov Timeval,180 ;Set a 10 second timeout
- call PNR ;Print 'Printer not ready'
- G5: call Getstat ;Get printer status
- test ah,10 ;Selected?
- jne G6 ;Yes
- cmp Timeval,0 ;Timed out?
- jne G5 ;No
- jmp Exit ;Yes, give up
- G6: call PIB ;Put old screen back
- pop cx,si ;Get old position and count
- jmp G4 ;and continue printing
-
- Getstat: mov ah,2
- int 17h
- ret
-
- PNR: push si
- mov si,Msg3
- PNR1: call Prompt
- pop si
- ret
-
- PIB: push si
- mov si,Buffer
- jmp PNR1
-
- ;Come here to install the program. ------------------------------------
- Initialize: jmp short Init1
- Msg4: db 13,10,'Selective Print Screen ver. 2.0 by Bob Montgomery'
- db ' installed.',13,10,'$'
- Init1: mov ah,Getvec
- mov al,5
- int DOS
- mov [Oldoff5],bx
- mov [Oldseg5],es
- mov ah,Setvec
- mov al,5
- mov dx,Newint5
- int DOS
- mov dx,Msg4
- mov ah,9
- int DOS
- mov dx,Initialize
- int 27h
-
-